home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
edit
/
thesrc20.zip
/
nonansi.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-26
|
24KB
|
736 lines
/***********************************************************************/
/* NONANSI.C - */
/* This file contains all calls to non-ansi conforming routines. */
/***********************************************************************/
/*
* THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
* Copyright (C) 1991-1995 Mark Hessling
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
*
* The Free Software Foundation, Inc.
* 675 Mass Ave,
* Cambridge, MA 02139 USA.
*
*
* If you make modifications to this software that you feel increases
* it usefulness for the rest of the community, please email the
* changes, enhancements, bug fixes as well as any and all ideas to me.
* This software is going to be maintained and enhanced as deemed
* necessary by the community.
*
* Mark Hessling email: M.Hessling@gu.edu.au
* 36 David Road Phone: +61 7 849 7731
* Holland Park Fax: +61 7 875 5314
* QLD 4121
* Australia
*/
/*
$Id: nonansi.c 2.0 1995/01/26 16:31:28 MH Release MH $
*/
#include <stdio.h>
#include <errno.h>
#include "the.h"
#include "proto.h"
#ifdef UNIX
#include <pwd.h>
#endif
/*#define DEBUG 1*/
#ifdef DOS
# include <dos.h>
# ifndef GO32
# include <direct.h>
# endif
#endif
#ifdef OS2
# ifndef EMX
# include <direct.h>
# endif
# include <io.h>
# ifndef S_IFMT
# define S_IFMT 0xF000
# endif
#endif
/***********************************************************************/
#ifdef PROTO
short file_readable(CHARTYPE *filename)
#else
short file_readable(filename)
CHARTYPE *filename;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("nonansi.c :file_readable");
#endif
if (!file_exists(filename))
{
#ifdef TRACE
trace_return();
#endif
return(TRUE);
}
if (access(filename,R_OK) == (-1))
{
#ifdef TRACE
trace_return();
#endif
return(FALSE);
}
#ifdef TRACE
trace_return();
#endif
return(TRUE);
}
/***********************************************************************/
#ifdef PROTO
short file_writable(CHARTYPE *filename)
#else
short file_writable(filename)
CHARTYPE *filename;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("nonansi.c :file_writable");
#endif
if (!file_exists(filename))
{
#ifdef TRACE
trace_return();
#endif
return(TRUE);
}
if (access(filename,W_OK) == (-1))
{
#ifdef TRACE
trace_return();
#endif
return(FALSE);
}
#ifdef TRACE
trace_return();
#endif
return(TRUE);
}
/***********************************************************************/
#ifdef PROTO
short file_exists(CHARTYPE *filename)
#else
short file_exists(filename)
CHARTYPE *filename;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("nonansi.c :file_exists");
#endif
if (access(filename,F_OK) == (-1))
{
#ifdef TRACE
trace_return();
#endif
return(FALSE);
}
#ifdef TRACE
trace_return();
#endif
return(TRUE);
}
/***********************************************************************/
#ifdef PROTO
short remove_file(CHARTYPE *filename)
#else
short remove_file(filename)
CHARTYPE *filename;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("nonansi.c :remove_file");
#endif
if(filename == NULL)
return(RC_OK);
#ifdef VMS
if (delete(filename) == (-1))
#else
if (unlink(filename) == (-1))
#endif
{
#ifdef TRACE
trace_return();
#endif
return(RC_ACCESS_DENIED);
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
#if defined(DOS) || defined(OS2)
/***********************************************************************/
#ifdef PROTO
short splitpath(CHARTYPE *filename)
#else
short splitpath(filename)
CHARTYPE *filename;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern CHARTYPE curr_path[MAX_FILE_NAME+1];
extern CHARTYPE sp_fname[MAX_FILE_NAME+1];
extern CHARTYPE sp_path[MAX_FILE_NAME+1];
/*--------------------------- local data ------------------------------*/
short len=0;
CHARTYPE work_filename[MAX_FILE_NAME+1] ;
CHARTYPE current_dir[MAX_FILE_NAME+1] ;
#if defined(DOS)
short new_dos_disk=0,current_dos_disk=0; /* 1 - A,2 - B... */
short temp_disk=0;
#endif
#ifdef OS2
ULONG logical_os2_drives=0L;
# ifdef __32BIT__
ULONG new_dos_disk=0L,current_dos_disk=0L,temp_disk=0L;
# else
USHORT new_dos_disk=0,current_dos_disk=0,temp_disk=0;
# endif
#endif
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("nonansi.c :splitpath");
#endif
strcpy(sp_path,"");
strcpy(sp_fname,"");
strcpy(work_filename,filename);
/*---------------------------------------------------------------------*/
/* If the supplied filename is empty, set the path = cwd and filename */
/* equal to blank. */
/*---------------------------------------------------------------------*/
if (strcmp(filename,"") == 0)
{
#if defined(EMX)
_getcwd2(sp_path,MAX_FILE_NAME);
#else
getcwd(sp_path,MAX_FILE_NAME);
#endif
strcpy(sp_fname,"");
}
/*---------------------------------------------------------------------*/
/* For DOS and OS/2, get current drive. */
/*---------------------------------------------------------------------*/
#ifdef DOS
# if defined(TC) || defined(GO32)
current_dos_disk = getdisk() + 1;
# else
_dos_getdrive(¤t_dos_disk);
# endif
#endif
#ifdef OS2
DosQueryCurrentDisk(¤t_dos_disk,&logical_os2_drives);
#endif
new_dos_disk = current_dos_disk;
/*---------------------------------------------------------------------*/
/* For DOS and OS/2, if a drive specified determine the drive number. */
/*---------------------------------------------------------------------*/
if (*(filename+1) == ':')/* we assume this means a drive secification */
new_dos_disk = (toupper(*(filename)) - 'A') + 1;
/*---------------------------------------------------------------------*/
/* For DOS and OS/2, change to the specified disk (if supplied and */
/* different). Validate the drive number. */
/*---------------------------------------------------------------------*/
if (new_dos_disk != current_dos_disk)
{
#ifdef DOS
# if defined(TC) || defined(GO32)
setdisk((short)(new_dos_disk-1));
temp_disk = getdisk()+1;
# else
_dos_setdrive(new_dos_disk,&temp_disk);
_dos_getdrive(&temp_disk);
# endif
#endif
#ifdef OS2
DosSetDefaultDisk(new_dos_disk);
DosQueryCurrentDisk(&temp_disk,&logical_os2_drives);
#endif
if (temp_disk != new_dos_disk) /* invalid drive */
{
#ifdef TRACE
trace_return();
#endif
return (RC_BAD_DRIVE);
}
}
/*---------------------------------------------------------------------*/
/* Save the current working directory on the specified drive, or the */
/* current drive if not specified. */
/*---------------------------------------------------------------------*/
#if defined(EMX)
_getcwd2(current_dir,MAX_FILE_NAME);
#else
getcwd(current_dir,MAX_FILE_NAME);
#endif
/*---------------------------------------------------------------------*/
/* If the work_filename contains a drive specifier, special handling is*/
/* needed. */
/*---------------------------------------------------------------------*/
switch(strlen(filename))
{
case 1:
break;
/*---------------------------------------------------------------------*/
/* If the filename consists only of a drive specifier, copy the current*/
/* directory for the now new drive into work_filename. */
/*---------------------------------------------------------------------*/
case 2:
if (*(filename+1) == ':')
strcpy(work_filename,current_dir);
break;
default:
if (*(filename+1) == ':'
&& *(filename+2) != ISLASH)
{
strcpy(work_filename,current_dir);
if (current_dir[strlen(current_dir)-1] != ISLASH)
strcat(work_filename,ISTR_SLASH);
strcat(work_filename,filename+2);
}
break;
}
/*---------------------------------------------------------------------*/
/* First determine if the supplied filename is a directory. */
/*---------------------------------------------------------------------*/
if (chdir(work_filename) == 0) /* valid directory */
{
#if defined(EMX)
_getcwd2(sp_path,MAX_FILE_NAME);
#else
getcwd(sp_path,MAX_FILE_NAME);
#endif
strcpy(sp_fname,"");
}
else /* here if the file is not a directory */
{
len = strzreveq(work_filename,ISLASH);
switch(len)
{
case (-1):
#if defined(EMX)
_getcwd2(sp_path,MAX_FILE_NAME);
#else
getcwd(sp_path,MAX_FILE_NAME);
#endif
strcpy(sp_fname,work_filename);
break;
case 0:
strcpy(sp_path,work_filename);
sp_path[1] = '\0';
strcpy(sp_fname,work_filename+1+len);
break;
default:
strcpy(sp_path,work_filename);
sp_path[len] = '\0';
strcpy(sp_fname,work_filename+1+len);
break;
}
}
if (strlen(sp_path) == 2
&& sp_path[1] == ':')
strcat(sp_path,ISTR_SLASH);
/*---------------------------------------------------------------------*/
/* Change directory to the supplied path, if possible and store the */
/* expanded path. */
/* If an error, restore the current path. */
/*---------------------------------------------------------------------*/
if (chdir(sp_path) != 0)
{
if (new_dos_disk != current_dos_disk)
{
chdir(current_dir);
#ifdef DOS
# if defined(TC) || defined(GO32)
setdisk((short)(current_dos_disk-1));
# else
_dos_setdrive(current_dos_disk,&temp_disk);
# endif
#endif
#ifdef OS2
DosSetDefaultDisk(new_dos_disk);
#endif
}
chdir(curr_path);
#ifdef TRACE
trace_return();
#endif
return(RC_FILE_NOT_FOUND);
}
/*---------------------------------------------------------------------*/
/* We are now in a valid directory, get the fully qualified directory */
/* name. */
/*---------------------------------------------------------------------*/
#if defined(EMX)
_getcwd2(sp_path,MAX_FILE_NAME);
#else
getcwd(sp_path,MAX_FILE_NAME);
#endif
/*---------------------------------------------------------------------*/
/* For DOS or OS/2, change back to the current directory of the now */
/* current disk and then change back to the original disk. */
/*---------------------------------------------------------------------*/
if (new_dos_disk != current_dos_disk)
{
if (chdir(current_dir) != 0)
{
#ifdef TRACE
trace_return();
#endif
return(RC_FILE_NOT_FOUND);
}
#ifdef DOS
# if defined(TC) || defined(GO32)
setdisk((short)(current_dos_disk-1));
# else
_dos_setdrive(current_dos_disk,&temp_disk);
# endif
#endif
#ifdef OS2
DosSetDefaultDisk(current_dos_disk);
#endif
}
chdir(curr_path);
/*---------------------------------------------------------------------*/
/* Append the OS directory character to the path if it doesn't already */
/* end in the character. */
/*---------------------------------------------------------------------*/
#ifndef VMS
len = strlen(sp_path);
if (len > 0)
if (sp_path[len-1] != ISLASH)
strcat(sp_path,(CHARTYPE *)ISTR_SLASH);
#endif
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
#else
/***********************************************************************/
#ifdef PROTO
short splitpath(CHARTYPE *filename)
#else
short splitpath(filename)
CHARTYPE *filename;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern CHARTYPE curr_path[MAX_FILE_NAME+1];
extern CHARTYPE sp_fname[MAX_FILE_NAME+1];
extern CHARTYPE sp_path[MAX_FILE_NAME+1];
extern struct stat stat_buf;
/*--------------------------- local data ------------------------------*/
short len=0;
CHARTYPE work_filename[MAX_FILE_NAME+1] ;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("nonansi.c :splitpath");
#endif
strcpy(sp_path,"");
strcpy(sp_fname,"");
strcpy(work_filename,filename);
/*---------------------------------------------------------------------*/
/* If the supplied filename is empty, set the path = cwd and filename */
/* equal to blank. */
/*---------------------------------------------------------------------*/
if (strcmp(filename,"") == 0)
{
getcwd(sp_path,MAX_FILE_NAME);
strcpy(sp_fname,"");
}
/*---------------------------------------------------------------------*/
/* Check if the first character is tilde; translate HOME env variable */
/* if there is one. Obviously only applicable to UNIX. */
/*---------------------------------------------------------------------*/
if (*(work_filename) == '~')
{
if (*(work_filename+1) == ISLASH)
{
strcpy(work_filename,(CHARTYPE *)getenv("HOME"));
strcat(work_filename,(filename+1));
}
else
{
struct passwd *pwd;
strcpy(sp_path,filename+1);
if ((len = strzeq(sp_path,ISLASH)) != (-1))
sp_path[len] = '\0';
if ((pwd = getpwnam(sp_path)) == NULL)
return(RC_BAD_FILEID);
strcpy(work_filename,pwd->pw_dir);
if (len != (-1))
strcat(work_filename,(filename+1+len));
}
}
/*---------------------------------------------------------------------*/
/* First determine if the supplied filename is a directory. */
/*---------------------------------------------------------------------*/
if ((stat(work_filename,&stat_buf) == 0)
&& (stat_buf.st_mode & S_IFMT) == S_IFDIR)
{
strcpy(sp_path,work_filename);
strcpy(sp_fname,"");
}
else /* here if the file doesn't exist or is not a directory */
{
len = strzreveq(work_filename,ISLASH);
switch(len)
{
case (-1):
getcwd(sp_path,MAX_FILE_NAME);
strcpy(sp_fname,work_filename);
break;
case 0:
strcpy(sp_path,work_filename);
sp_path[1] = '\0';
strcpy(sp_fname,work_filename+1+len);
break;
default:
strcpy(sp_path,work_filename);
sp_path[len] = '\0';
strcpy(sp_fname,work_filename+1+len);
break;
}
}
/*---------------------------------------------------------------------*/
/* Change directory to the supplied path, if possible and store the */
/* expanded path. */
/* If an error, restore the current path. */
/*---------------------------------------------------------------------*/
if (chdir(sp_path) != 0)
{
chdir(curr_path);
#ifdef TRACE
trace_return();
#endif
return(RC_FILE_NOT_FOUND);
}
getcwd(sp_path,MAX_FILE_NAME);
chdir(curr_path);
/*---------------------------------------------------------------------*/
/* Append the OS directory character to the path if it doesn't already */
/* end in the character. */
/*---------------------------------------------------------------------*/
#ifndef VMS
len = strlen(sp_path);
if (len > 0)
if (sp_path[len-1] != ISLASH)
strcat(sp_path,(CHARTYPE *)ISTR_SLASH);
#endif
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
#endif
#if defined(NO_RENAME)
/***********************************************************************/
#ifdef PROTO
short rename(CHARTYPE *path1,CHARTYPE *path2)
#else
short rename(path1,path2)
CHARTYPE *path1;
CHARTYPE *path2;
#endif
/***********************************************************************/
/* Function : Emulate missing rename() function missing from SystemV */
/* Parameters: path1 - old filename */
/* path2 - new_filename */
/* Return : 0 on success, -1 on error */
/***********************************************************************/
{
#ifdef TRACE
trace_function("nonansi.c :rename");
#endif
if (link(path1,path2) != 0)
{
#ifdef TRACE
trace_return();
#endif
return(-1);
}
if (unlink(path1) != 0)
{
#ifdef TRACE
trace_return();
#endif
return(-1);
}
#ifdef TRACE
trace_return();
#endif
return(0);
}
#endif
#ifdef OS2
# ifdef __32BIT__
# define FSQBUFFERSIZE 64
/***********************************************************************/
bool LongFileNames(CHARTYPE *path)
/***********************************************************************/
/* Function : Determine if file system allows long file names. (HPFS) */
/* This is the 32-bit version. */
/* Parameters: path - directory path */
/* Return : 1 if file system is HPFS */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
ULONG nDrive=0L;
ULONG lMap=0L;
char buffer[FSQBUFFERSIZE];
FSQBUFFER2 *bData = (FSQBUFFER2 *) buffer;
char bName[3];
ULONG bDataLen=0L;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("file.c: LongFileNames");
#endif
if ((strlen (path) > 0) && path [1] == ':')
bName[0] = path[0];
else
{
DosQueryCurrentDisk(&nDrive, &lMap);
bName[0] = (char) (nDrive + 'A' - 1);
}
bName[1] = ':';
bName[2] = 0;
bDataLen = FSQBUFFERSIZE;
DosQueryFSAttach(bName, 0, FSAIL_QUERYNAME, bData, &bDataLen);
return(strcmp(bData->szFSDName + bData->cbName, "HPFS") == 0);
}
# else
/***********************************************************************/
bool LongFileNames(CHARTYPE *path)
/***********************************************************************/
/* Function : Determine if file system allows long filenames. (HPFS) */
/* This is the 16-bit version. */
/* Parameters: path - directory path */
/* Return : 1 if file system is HPFS */
/***********************************************************************/
{
typedef struct _FSNAME {
USHORT cbName;
UCHAR szName[1];
} FSNAME;
typedef struct _FSQINFO {
USHORT iType;
FSNAME Name;
UCHAR rgFSAData[59];
} FSQINFO;
typedef FSQINFO FAR *PFSQINFO;
/*--------------------------- local data ------------------------------*/
USHORT nDrive=0,cbData=0;
ULONG lMap=0L;
FSQINFO bData;
BYTE bName[3];
FSNAME *pFSName=NULL;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("file.c: LongFileNames");
#endif
if ((strlen(path) > 0) && path[1] == ':')
bName[0] = path[0];
else
{
DosQueryCurrentDisk(&nDrive, &lMap);
bName[0] = (char)(nDrive + '@');
}
bName[1] = ':';
bName[2] = 0;
cbData = sizeof(bData);
DosQFSAttach((PSZ)bName,0,1,(PBYTE)&bData,&cbData,0L);
pFSName = &bData.Name;
(CHARTYPE *)pFSName += pFSName->cbName + sizeof(pFSName->cbName)+1;
return(strcmp((CHARTYPE *)&(pFSName->szName[0]),"HPFS") == 0);
}
# endif
#endif
#ifdef PRE_111_GO32
/***********************************************************************/
#ifdef PROTO
short getdisk(void)
#else
short getdisk()
#endif
/***********************************************************************/
/* Function : Determine the drive letter for the current disk. */
/* Parameters: nil */
/* Return : 0 for drive A:, 1 for drive B:, etc... */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
regs.h.ah = 0x19;
int86(0x21, ®s, ®s);
return ((short) regs.h.al);
}
/***********************************************************************/
#ifdef PROTO
short setdisk(short drive)
#else
short setdisk(drive)
short drive;
#endif
/***********************************************************************/
/* Function : Change the current drive to that specified. */
/* Parameters: 0 for drive A:, 2 for drive B:, etc... */
/* Return : number of drives present */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
regs.h.ah = 0x0e;
regs.h.dl = (char)drive;
int86(0x21, ®s, ®s);
return ((short) regs.h.al);
}
#endif